package com.powernode.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.constant.ManagerConstants;
import com.powernode.domain.SysMenu;
import com.powernode.ex.headler.BusinessException;
import com.powernode.mapper.SysMenuMapper;
import com.powernode.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@CacheConfig(cacheNames = "com.powernode.service.impl.SysMenuServiceImpl")  //命名空间 保证唯一性
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    private SysMenuMapper sysMenuMapper;


    @Cacheable(key = "#loginUserId")    // 缓存key
    @Override
    public Set<SysMenu> queryUserMenuListByUserId(Long loginUserId) {
//        根据用户标识查询菜单权限集合
        Set<SysMenu> menus = sysMenuMapper.selectUserMenuListByUserId(loginUserId);
//        将菜单权限集合转换为层级关系
        return transformTree(menus, 0L);
    }

    @Override
    @Cacheable(key = ManagerConstants.SYS_ALL_MENU_KEY)
    public List<SysMenu> queryAllSysMenuList() {
        return sysMenuMapper.selectList(null);
    }

    /**
     * 保存菜单权限
     *
     * @param sysMenu 菜单权限
     * @return 保存结果
     */
    @CacheEvict(key = ManagerConstants.SYS_ALL_MENU_KEY)
    @Override
    public Boolean saveSysMenu(SysMenu sysMenu) {
        return sysMenuMapper.insert(sysMenu) > 0;
    }

    /**
     * 修改菜单权限
     *
     * @param sysMenu 菜单权限
     * @return
     */
    @CacheEvict(key = ManagerConstants.SYS_ALL_MENU_KEY)
    @Override
    public Boolean modifySysMenu(SysMenu sysMenu) {
        Integer type = sysMenu.getType();
        if (type == 0) {
            sysMenu.setParentId(0L);
        }
        return sysMenuMapper.updateById(sysMenu) > 0;
    }

    /**
     * 删除菜单权限
     *
     * @param menuId 菜单权限标识
     * @return
     */
    @CacheEvict(key = ManagerConstants.SYS_ALL_MENU_KEY)
    @Override
    public Boolean removeSysMenuById(Long menuId) {
//        根据菜单标识查询子菜单集合
        List<SysMenu> menuList = sysMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>()
                .eq(SysMenu::getParentId, menuId));
        // 判断子菜单集合是否有值
        if (CollectionUtil.isNotEmpty(menuList) && menuList.size() != 0) {
//            当前菜单节点包含子节点 不可以进行删除
            throw new BusinessException("当前菜单节点包含子节点 不可以进行删除");
        }
//        当前菜单节点不包含子节点，可以进行删除
        return sysMenuMapper.deleteById(menuId) > 0;
    }


    /**
     * 递归转换菜单权限集合为层级关系
     * 1. 已知菜单深度 <=2
     * 2. 未知菜单深度
     *
     * @param menus 菜单
     * @param pid   0
     * @return
     */
    private Set<SysMenu> transformTree(Set<SysMenu> menus, Long pid) {
        // todo 1 已知菜单深度小于等于2
        //从菜单集合中获取根节点集合
//        Set<SysMenu> roots = menus.stream()
//                .filter(m -> m.getParentId().equals(pid))
//                .collect(Collectors.toSet());
//
//        roots.forEach(root -> {
//            Set<SysMenu> child = menus.stream()
//                    .filter(m -> m.getParentId().equals(root.getMenuId()))
//                    .collect(Collectors.toSet());
//            root.setList(child);
//        });

        // todo 2 未知菜单深度
        Set<SysMenu> roots = menus.stream()
                .filter(m -> m.getParentId().equals(pid))
                .collect(Collectors.toSet());
        roots.forEach(r -> r.setList(transformTree(menus, r.getMenuId())));
        return roots;
    }
}
